﻿using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.IT;
using Coldairarrow.Entity.PB;
using Coldairarrow.Entity.Print;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using Coldairarrow.Util.ClassLibrary;
using Coldairarrow.Util.Helper;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_LocationBusiness : BaseBusiness<PB_Location>, IPB_LocationBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IOperatorDept _opdept;
        public PB_LocationBusiness(IDbAccessor db, IOperator @operator, IOperatorDept @opdept)
            : base(db)
        {
            _operator = @operator;
            _opdept = @opdept;
        }

        #region 外部接口



        public async Task<List<PB_Location>> GetDataListAsync()
        {
            var q = GetIQueryable();
            return await q.ToListAsync();
        }

        public async Task<PB_Location> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        [DataAddLog(UserLogType.货位管理, "Name", "货位")]
        [DataRepeatValidate(new string[] { "Code" }, new string[] { "货位" }, allData: false, matchOr: false)]
        public async Task AddDataAsync(PB_Location data)
        {
            data.QrCode = h_Location + "," + data.Id;
            await InsertAsync(data);
        }

        [DataEditLog(UserLogType.货位管理, "Name", "货位")]
        [DataRepeatValidate(new string[] { "Code" }, new string[] { "货位" }, allData: false, matchOr: false)]
        public async Task UpdateDataAsync(PB_Location data)
        {
            data.QrCode = h_Location + "," + data.Id;
            await UpdateAsync(data);
        }

        [DataDeleteLog(UserLogType.货位管理, "Name", "货位")]
        public async Task DeleteDataAsync(List<string> ids)
        {
            List<IT_LocalMaterial> LocalMaterialList = await Db.GetIQueryable<IT_LocalMaterial>().Where(x => ids.Contains(x.LocalId)).ToListAsync();
            if (LocalMaterialList.Count > 0)
            {
                throw new BusException("货位使用中不允许删除");
            }
            await DeleteAsync(ids);
        }

        public async Task ModifyEnableAsync(string Id)
        {
            var entity = await GetEntityAsync(Id);
            if (entity.IsForbid)
            {
                entity.IsForbid = false;
                if (entity.IsDefault) entity.IsDefault = false;
            }
            else
            {
                entity.IsForbid = true;
            }

            await UpdateAsync(entity);
        }

        public async Task AddDataExlAsync(List<PB_Location> list)//void
        {
            await InsertAsync(list);   //  BulkInsert    InsertAsync    

        }

        public IQueryable<T> GetQueryable<T>() where T : class, new()
        {
            return Db.GetIQueryable<T>();
        }
        
        public async Task<AjaxResult> SelectLocationID(PB_LocationPrint data, MongoDBOptions _mongodbOptions)
        {
            try
            {

                int i = 0;
                List<string> List = new List<string>();
                foreach (var item in data.LocationID)
                {
                    List.Add(item);
                    i = List.Count;
                }
                string timestamp = GetTimeStamp();
                var q = GetIQueryable();
                List<PrintQueue> printqueue = new List<PrintQueue>();
                var res = q = q.Where(m => List.Contains(m.Id));
                var k = await Db.GetIQueryable<Base_Department>().Where(m => m.Id == _operator.Property.DepartmentId).FirstOrDefaultAsync();
                string strguid = Guid.NewGuid().ToString("N");
                foreach (var item in res)
                {
                    DataTable de = await Db.GetDataTableWithSqlAsync("select Name from PB_StorArea where Id='" + item.AreaId + "' Limit 1");
                    DataTable de2 = await Db.GetDataTableWithSqlAsync("select Name from PB_Rack where Id='" + item.RackId + "' Limit 1");
                    PB_Location Location = new PB_Location();
                    PrintQueue printdata = new PrintQueue();
                    printdata.Id = IdHelper.GetId();
                    printdata.No = item.Id;//编号
                    //if (de.Rows[0][0].IsNullOrEmpty())
                    //{
                    //    printdata.Name = item.Name;
                    //}
                    //if (de2.Rows[0][0].IsNullOrEmpty()) {
                    //    printdata.Name = item.Name;
                      
                    //}
                    printdata.Name = de.Rows[0][0].ToString() + "/" + de2.Rows[0][0].ToString() + "/" + item.Name;

                    printdata.Date = DateTime.Now.ToString("yyyy-MM-dd");//生产日期当前时间
                    printdata.Dept = k.Name;//当前登录人所在组织
                    printdata.QrCode = item.QrCode;//货位编号
                    printdata.Type = Skill_Type.Location.ToString();//货位
                    printdata.Status = "0";
                    printdata.Printer =data.PrintID;
                    printdata.TypeName = "货位";
                    printdata.BatchNumber = strguid;
                    printdata.JobCount = i ;
                    printdata.IsProduct = false;
                    printdata.Code = item.Code;
                    printqueue.Add(printdata);
                }
                MongoDBHelper mongo = new MongoDBHelper(_mongodbOptions);
                await mongo.InsertManyAsync<PrintQueue>(PrintQueueCollection, printqueue);
                AjaxResult resIn = new AjaxResult
                {
                    Success = true,
                    Msg = "打印成功"
                };
                return  resIn;
            }
            catch (Exception)
            {
                AjaxResult res = new AjaxResult
                {
                    Success = false,
                    Msg = "打印失败！数据错误请检查数据"
                };
                return res;
            }
        }

        public  async Task<List<PB_LocationlistDto>> Selectid(string id)
        {
            Expression<Func<PB_Location, Base_Department, PB_StorArea,PB_Rack,PB_Project,PB_LocationlistDto>> select = (a, b,c,d,e) => new PB_LocationlistDto
            {
                StordName = b.Name,
                AreaName=c.Name,
                RackName=d.Name,
                ProjectName=e.Name,
               
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.StorId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<PB_StorArea>() on a.AreaId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<PB_Rack>() on a.RackId equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    join e in Db.GetIQueryable<PB_Project>() on a.ProjectId equals e.Id into ae
                    from e in ae.DefaultIfEmpty()
                    select @select.Invoke(a, b,c,d,e);
            string[] arr = id.Split(',');
            List<string> List = new List<string>();
            foreach (var item in arr)
            {
                List.Add(item);
            }
            q = q.Where(m => List.Contains(m.Id));
            return await q.ToListAsync();
        }

        /// <summary>
        /// 获取货位库存的详细信息
        /// </summary>
        /// <param name="locaId">货位Id</param>
        /// <returns></returns>
        public async Task<List<LocaMaterialDetailDTO>> GetLocaMaterialDetailAsync(string locaId)
        {
            //string sqlMain = @"select * from ( select a.PackId,b.BoxName,a.MaterialId,c.`Code` as MaterialCode,c.Spec as MaterialSpec,CONCAT(e.`Name`,'/',f.`Name`,'/',d.`Name`) as LocalName,a.Num,b.QrCode from IT_LocalDetail as a join PB_PackList as b on a.PackId=b.Id join PB_Material as c on a.MaterialId=c.Id join PB_Location as d on a.LocalId=d.Id join PB_StorArea as e on d.AreaId=e.Id join PB_Rack as f on d.RackId=f.Id where a.LocalId='" + locaId + "' and b.PackageType=0  UNION ALL select PackId,BoxName,'' as MaterialId,'' as MaterialCode,'' as MaterialSpec,LocalName,SUM(Num) as Num,QrCode from ( select a.PackId,b.BoxName,a.Num,CONCAT(d.`Name`,'/',e.`Name`,'/',c.`Name`) as LocalName,b.QrCode from IT_LocalDetail as a join PB_PackList as b on a.PackId=b.Id join PB_Location as c on a.LocalId=c.Id join PB_StorArea as d on c.AreaId=d.Id join PB_Rack as e on c.RackId=e.Id where a.LocalId='" + locaId + "' and b.PackageType=1 )as t group by PackId,BoxName,LocalName,QrCode  UNION ALL  select PackId,BoxName,MaterialId,MaterialCode,MaterialSpec,LocalName,SUM(Num) as Num,CONCAT('04',',',MaterialId) as QrCode from (  select a.PackId,b.`Name` as BoxName,a.MaterialId,b.`Code` as MaterialCode,b.Spec as MaterialSpec,CONCAT(d.`Name`,'/',e.`Name`,'/',c.`Name`) as LocalName,a.Num from IT_LocalDetail as a join PB_Material as b on a.MaterialId=b.Id join PB_Location as c on a.LocalId=c.Id join PB_StorArea as d on c.AreaId=d.Id join PB_Rack as e on c.RackId=e.Id where a.LocalId='" + locaId + "' and a.PackId='')as t group by PackId,BoxName,MaterialId,MaterialCode,MaterialSpec,LocalName ) as t order by MaterialCode";
            string sql = @"select * from ( 
select a.PackId as Id,a.PackId,b.BoxName,a.MaterialId,c.`Code` as MaterialCode,c.Spec as MaterialSpec,CONCAT(e.`Name`,'/',f.`Name`,'/',d.`Name`) as LocalName,a.Num,b.QrCode,a.JobId,'0' as Type from IT_LocalDetail as a join PB_PackList as b on a.PackId=b.Id join PB_Material as c on a.MaterialId=c.Id join PB_Location as d on a.LocalId=d.Id join PB_StorArea as e on d.AreaId=e.Id join PB_Rack as f on d.RackId=f.Id where a.LocalId='{0}' and b.PackageType=0  
UNION ALL 
select PackId as Id,PackId,BoxName,'' as MaterialId,'' as MaterialCode,'' as MaterialSpec,LocalName,SUM(Num) as Num,QrCode,JobId,'0' as Type from ( select a.PackId,b.BoxName,a.Num,CONCAT(d.`Name`,'/',e.`Name`,'/',c.`Name`) as LocalName,b.QrCode,a.JobId from IT_LocalDetail as a join PB_PackList as b on a.PackId=b.Id join PB_Location as c on a.LocalId=c.Id join PB_StorArea as d on c.AreaId=d.Id join PB_Rack as e on c.RackId=e.Id where a.LocalId='{0}' and b.PackageType=1 )as t group by PackId,BoxName,LocalName,QrCode,JobId
UNION ALL  
select MaterialId as Id,PackId,BoxName,MaterialId,MaterialCode,MaterialSpec,LocalName,SUM(Num) as Num,CONCAT('04',',',MaterialId) as QrCode,JobId,'1' as Type from (  
select a.PackId,b.`Name` as BoxName,a.MaterialId,b.`Code` as MaterialCode,b.Spec as MaterialSpec,CONCAT(d.`Name`,'/',e.`Name`,'/',c.`Name`) as LocalName,a.Num,a.JobId from IT_LocalDetail as a join PB_Material as b on a.MaterialId=b.Id join PB_Location as c on a.LocalId=c.Id join PB_StorArea as d on c.AreaId=d.Id join PB_Rack as e on c.RackId=e.Id where a.LocalId='{0}' and a.PackId='' and a.JobId=''
)as t group by PackId,BoxName,MaterialId,MaterialCode,MaterialSpec,LocalName,JobId 
UNION ALL 
select a.JobId as Id,a.PackId,b.`Name` as BoxName,a.MaterialId,b.`Code` as MaterialCode,b.Spec as MaterialSpec,CONCAT(d.`Name`,'/',e.`Name`,'/',c.`Name`) as LocalName,a.Num,CONCAT('14',',',a.JobId) as QrCode,JobId,'2' as Type from IT_LocalDetail as a join PB_Material as b on a.MaterialId=b.Id join PB_Location as c on a.LocalId=c.Id join PB_StorArea as d on c.AreaId=d.Id join PB_Rack as e on c.RackId=e.Id where a.LocalId='{0}' and a.JobId!=''
) as t order by MaterialCode";
            string sqlMain = string.Format(sql, locaId);
            List<LocaMaterialDetailDTO> listdata = await Db.GetListBySqlAsync<LocaMaterialDetailDTO>(sqlMain);
            if (listdata.Count > 0)
            {
                return listdata;
            }
            else
            {
                throw new BusException("暂无数据");
            }
        }

        /// <summary>
        /// 打印仓库里货位对应的包码或物料码
        /// </summary>
        /// <param name="data"></param>
        /// <param name="PrinterId">打印机Id</param>
        /// <param name="_mongodbOptions"></param>
        /// <returns></returns>
        public async Task PrintPackCodeAsync(List<LocaMaterialDetailDTO> data, string PrinterId, MongoDBOptions _mongodbOptions)
        {
            List<PrintQueue> printqueue = new List<PrintQueue>();
            var deptdata = await _opdept.GetOperatorDept();
            string timestamp = Guid.NewGuid().ToString("N");
            foreach (var item in data)
            {
                PrintQueue pq = new PrintQueue();
                pq.Id = IdHelper.GetId();
                pq.No = item.Id;
                pq.Name = item.BoxName;
                pq.Date = DateTime.Now.ToString("yyyy-MM-dd");
                pq.Dept = deptdata.DeptName;
                pq.QrCode = item.QrCode;
                pq.TypeName = item.MaterialSpec;
                if (item.Type == 0)
                {
                    pq.Type = Skill_Type.Package.ToString();
                }
                else
                {
                    pq.Type = Skill_Type.Statistics.ToString();
                }
                pq.Status = item.Num.ToString();
                pq.Printer = PrinterId;
                pq.IsProduct = true;
                pq.Code = item.MaterialCode;
                pq.BatchNumber = timestamp;
                pq.JobCount = data.Count();
                printqueue.Add(pq);
            }
            MongoDBHelper mongo = new MongoDBHelper(_mongodbOptions);
            await mongo.InsertManyAsync<PrintQueue>(PrintQueueCollection, printqueue);
        }

        #endregion

        #region 私有成员

        #endregion
    }
}